
package com.be.beadmin.product.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.design.entity.Process;
import com.be.beadmin.design.repository.ProcessRepository;
import com.be.beadmin.product.dto.input.PlantCapacityCalendarDto;
import com.be.beadmin.product.dto.output.*;
import com.be.beadmin.product.dto.output.CapacityByBatchAndDayEx;
import com.be.beadmin.product.entity.PlantCapacityCalendar;
import com.be.beadmin.product.entity.PlantCapacityCalendar_;
import com.be.beadmin.product.entity.ProductManufactInfor;
import com.be.beadmin.product.entity.UserWorkHourInfo;
import com.be.beadmin.product.mapper.PlantCapacityCalendarMapper;
import com.be.beadmin.product.mapper.PlantCapacityCalendarMapperEx;
import com.be.beadmin.product.repository.PlantCapacityCalendarRepository;
import com.be.beadmin.product.repository.ProductManufactInforRepository;
import com.be.beadmin.product.repository.UserWorkHourInfoRepository;
import com.be.beadmin.product.repository.WorkOrderInforRepository;
import com.be.beadmin.product.service.PlantCapacityCalendarService;
import com.be.beadmin.project.entity.BatchPlan;
import com.be.beadmin.project.entity.BatchProduct;
import com.be.beadmin.project.entity.Info;
import com.be.beadmin.project.repository.BatchPlanRepository;
import com.be.beadmin.project.repository.BatchProductRepository;
import com.be.beadmin.project.repository.MasterPlanRepository;
import com.be.beadmin.project.service.BatchPlanService;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.service.entity.FactoryCalendar;
import com.be.beadmin.service.entity.FactoryCalendarItem;
import com.be.beadmin.service.repository.FactoryCalendarItemRepository;
import com.be.beadmin.service.repository.FactoryCalendarRepository;
import com.be.beadmin.service.service.FactoryCalendarItemService;
import com.be.beadmin.service.util.DateUtil;
import com.be.beadmin.service.util.NumberUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author zjm
 * @description 服务实现
 * @date 2023-03-26
 **/
@Service
@RequiredArgsConstructor
public class PlantCapacityCalendarServiceImpl implements PlantCapacityCalendarService {
    @Autowired
    private FactoryCalendarRepository factoryCalendarRepository;

    @Autowired
    private UserWorkHourInfoRepository userWorkHourInfoRepository;
    @Autowired
    private BatchProductRepository batchProductRepository;

    @Autowired
    private BatchPlanRepository batchPlanRepository;

    @Autowired
    private BatchPlanService batchPlanService;
    @Autowired
    private ProcessRepository processRepository;
    @Autowired
    private WorkOrderInforRepository workOrderInforRepository;
    @Autowired
    private PlantCapacityCalendarRepository plantCapacityCalendarRepository;
    @Autowired
    private PlantCapacityCalendarMapper plantCapacityCalendarMapper;

    @Resource(name = "plantCapacityCalendarMapperExImplExtend")
    private PlantCapacityCalendarMapperEx plantCapacityCalendarMapperEx;

    @Autowired
    private FactoryCalendarItemService factoryCalendarItemService;

    @Autowired
    private ProductManufactInforRepository productManufactInforRepository;

    @Autowired
    private InfoService infoService;

    @Autowired
    private MasterPlanRepository masterPlanRepository;
    @Autowired
    private FactoryCalendarItemRepository factoryCalendarItemRepository;

    @Override
    public Page<PlantCapacityCalendarEx> getPlantCapacityCalendarByPage(PageEntity pageEntity) {


        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
//        for (FilderExpressEntity filter : pageEntity.getFilters()) {
//            if (filter.getField().equals("projectCode") || filter.getField().equals("projectName")) { // 这两个没办法
//
//            }
//        }


        Page<PlantCapacityCalendar> page = plantCapacityCalendarRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilderNew.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.delete), 0); //过滤为0
                    list.add(pre2);
//                    Predicate pre3 = criteriaBuilder.equal(root.get(PlantCapacityCalendar_.workHour), 0); //过滤为0
//                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(PlantCapacityCalendar_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);

        Page<PlantCapacityCalendarEx> page1 = page.map(plantCapacityCalendarMapperEx::toEntity);

//        Page<PlantCapacityCalendarEx> page1 = page.map(new Function<PlantCapacityCalendar, PlantCapacityCalendarEx>() {
//            @Override
//            public PlantCapacityCalendarEx apply(PlantCapacityCalendar plantCapacityCalendar) {
//                PlantCapacityCalendarEx plantCapacityCalendarEx = plantCapacityCalendarMapperEx.toEntity(plantCapacityCalendar);
//                Info info = plantCapacityCalendarRepository.findInfoByPlantCapacityCalendarId(plantCapacityCalendar.getId());
////                BatchPlan batchPlanById = batchPlanService.getBatchPlanById(plantCapacityCalendar.getBatchPlanId());
////                if (batchPlanById == null) {
////                    plantCapacityCalendarEx.setProjectName(null);
////                    plantCapacityCalendarEx.setProjectCode(null);
////                    return plantCapacityCalendarEx;
////                }
////                MasterPlan masterPlanByIdAndDelete = masterPlanRepository.findMasterPlanByIdAndDelete(batchPlanById.getMasterPlanId(), 0);
////                if (masterPlanByIdAndDelete == null) {
////                    plantCapacityCalendarEx.setProjectName(null);
////                    plantCapacityCalendarEx.setProjectCode(null);
////                    return plantCapacityCalendarEx;
////                }
////                Info infoIdById = infoService.getInfoIdById(masterPlanByIdAndDelete.getInfoId());
////                if (infoIdById == null) {
////                    plantCapacityCalendarEx.setProjectName(null);
////                    plantCapacityCalendarEx.setProjectCode(null);
////                    return plantCapacityCalendarEx;
////                }
//                if (info == null) {
//                    plantCapacityCalendarEx.setProjectName(null);
//                    plantCapacityCalendarEx.setProjectCode(null);
//                    return plantCapacityCalendarEx;
//                }
//                plantCapacityCalendarEx.setProjectName(info.getProjectName());
//                plantCapacityCalendarEx.setProjectCode(info.getProjectCode());
//                return plantCapacityCalendarEx;
//            }
//        });
        return page1;

    }

    @Override
    public void addPlantCapacityCalendar(PlantCapacityCalendarDto plantCapacityCalendarDto) {
        PlantCapacityCalendar result = plantCapacityCalendarRepository.findPlantCapacityCalendarByIdAndDelete(plantCapacityCalendarDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("PlantCapacityCalendar不存在,请重新查询");
        }
        PlantCapacityCalendar plantCapacityCalendar = plantCapacityCalendarMapper.toEntity(plantCapacityCalendarDto);
        plantCapacityCalendarRepository.save(plantCapacityCalendar);
    }

    @Override
    public void updatePlantCapacityCalendar(PlantCapacityCalendarDto plantCapacityCalendarDto) {
        PlantCapacityCalendar plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarById(plantCapacityCalendarDto.getId());
        plantCapacityCalendar = plantCapacityCalendarMapper.toEntity(plantCapacityCalendarDto);
        plantCapacityCalendarRepository.save(plantCapacityCalendar);
    }


    @Override
    public void delPlantCapacityCalendar(String id) {
        PlantCapacityCalendar plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarById(id);
        plantCapacityCalendar.setDelete(1);
        plantCapacityCalendarRepository.save(plantCapacityCalendar);
    }

    @Override
    public void delPlantCapacityCalendars(List<String> ids) {
    }

    /**
     * 生成计划产能日历
     *
     * @param productManufactInfor
     * @param bp
     * @param factoryCalendar
     * @param batchPlan
     * @return
     */
    @Override
    public void generateCapacityCalendar(ProductManufactInfor productManufactInfor, BatchProduct bp, FactoryCalendar factoryCalendar, BatchPlan batchPlan) {

        if (batchPlan == null) {
            throw new BeadminException("没有找到批次计划， 无法统计该柜体的产能");
        }
        Info info = productManufactInforRepository.findInfoByProductManufactInforAndDelete(productManufactInfor.getId(), 0);

//        Info info = infoService.getInfoIdById(batchPlan.getId());
        int isSchduling = batchPlanRepository.findIsSchduling(batchPlan.getId(), 0);
        if (isSchduling == 1) {
            return;
        }
        batchPlan.setIsSchduling(1);
        batchPlanRepository.save(batchPlan);
        // 该工序的计划开始时间
        Date date = productManufactInfor.getPlanManufactStartDate();

        date = DateUtil.transDateFormat(date);
        int noDayOffs = 0;
        while (date.before(DateUtil.transDateFormat(productManufactInfor.getPlanManufactEndDate())) || date.equals(DateUtil.transDateFormat(productManufactInfor.getPlanManufactEndDate()))) {
            FactoryCalendarItem fci = factoryCalendarItemRepository.findFactoryCalendarItemByDateAndFactoryCalendarAndDelete(date, factoryCalendar, 0);
            if (fci != null) {
                if (fci.getDayOff()) {
                    date = DateUtil.computeDate(date, 24);
                    continue;
                }
            }

            noDayOffs++;
            date = DateUtil.computeDate(date, 24);
        }
        // 更新产能日历
//        for (Date date = )
        System.out.println("productManufactInfor.getStandManufactWorkhour():" + productManufactInfor.getStandManufactWorkhour());
        System.out.println("noDayOffs" + noDayOffs);
        int workLoad = Math.round((productManufactInfor.getStandManufactWorkhour()==null?0:productManufactInfor.getStandManufactWorkhour()) / noDayOffs);
        date = DateUtil.transDateFormat(productManufactInfor.getPlanManufactStartDate());
        List<PlantCapacityCalendar> plantCapacityCalendars = new ArrayList<>();
        while (date.before(DateUtil.transDateFormat(productManufactInfor.getPlanManufactEndDate())) || date.equals(DateUtil.transDateFormat(productManufactInfor.getPlanManufactEndDate()))) {

            FactoryCalendarItem fci = factoryCalendarItemRepository.findFactoryCalendarItemByDateAndFactoryCalendarAndDelete(date, factoryCalendar, 0);
            if (fci != null) {
                if (fci.getDayOff()) {
                    date = DateUtil.computeDate(date, 24);
                    continue;
                }
            }

            PlantCapacityCalendar plantCapacityCalendar = null;
            // 根据柜体id和工序id和时间获取到某天的产能
            if (bp != null) {
                plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchProductIdAndDateAndProcessIdAndDelete(bp.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), 0);
            } else {
                plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchPlanIdAndDateAndProcessIdAndDelete(batchPlan.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), 0);

//                List<PlantCapacityCalendar> plants = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchPlanIdAndDateAndProcessIdAndDelete(batchPlan.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), 0);
//                if (!plants.isEmpty()) {
//                    plantCapacityCalendar = plants.get(0);
//                }
            }
            if (plantCapacityCalendar == null) {
                plantCapacityCalendar = new PlantCapacityCalendar();
                plantCapacityCalendar.setWorkHour((float) 0);
                plantCapacityCalendar.setRealWorkHour((float) 0);
            }
            plantCapacityCalendar.setDate(DateUtil.computeDate(date, 9));
            if (bp != null) {
                plantCapacityCalendar.setBatchProductId(bp.getId());
                plantCapacityCalendar.setBatchProductCode(bp.getProductCode());
            }
            plantCapacityCalendar.setProjectName(batchPlan.getProjectName());
            plantCapacityCalendar.setProjectCode(info == null ? null : info.getProjectCode());
            plantCapacityCalendar.setBatchPlanId(batchPlan.getId());
            plantCapacityCalendar.setBatchPlanCode(batchPlan.getBatchPlanCode());
            plantCapacityCalendar.setProcessName(productManufactInfor.getProcessName());
            plantCapacityCalendar.setProcessCode(productManufactInfor.getProcessCode());
            plantCapacityCalendar.setProcessSequence(productManufactInfor.getSequence());
            plantCapacityCalendar.setProcessId(productManufactInfor.getProcessId());
            plantCapacityCalendar.setWorkHour(plantCapacityCalendar.getWorkHour() + workLoad);
//            plantCapacityCalendar.setRealWorkHour((float) 0);
            plantCapacityCalendars.add(plantCapacityCalendar);
//                plantCapacityCalendar.set
//            plantCapacityCalendarRepository.save(plantCapacityCalendar);
            date = DateUtil.computeDate(date, 24);

        }
        plantCapacityCalendarRepository.saveAll(plantCapacityCalendars);
        batchPlan.setIsSchduling(0);
        batchPlanRepository.save(batchPlan);

    }

    /**
     * 生成实际产能日历
     *
     * @param productManufactInfor
     * @param userWorkHourInfo
     * @return
     */
    @Override
    public void generateRealCapacityCalendar(ProductManufactInfor productManufactInfor, UserWorkHourInfo userWorkHourInfo, BatchProduct bp, FactoryCalendar factoryCalendar, BatchPlan batchPlan) {
        BatchProduct product = batchProductRepository.findBatchProductByIdAndDelete(productManufactInfor.getBatchProductId(), 0);
        Info info = productManufactInforRepository.findInfoByProductManufactInforAndDelete(productManufactInfor.getId(), 0);
        if (batchPlan == null) {
            throw new BeadminException("没有找到批次计划， 无法统计该柜体的产能");
        }
//        Info info = infoService.getInfoIdById(batchPlan.getId());
        int isSchduling = batchPlanRepository.findIsSchduling(batchPlan.getId(), 0);
        if (isSchduling == 1) {
            return;
        }
        batchPlan.setIsSchduling(1);
        batchPlanRepository.save(batchPlan);

        // 该工序的实际开始时间
        Date startDate = productManufactInfor.getManufactStartDate();
        // 该工序的实际结束时间
        Date endDate = productManufactInfor.getManufactEndDate();
        if (startDate == null) {
            batchPlan.setIsSchduling(0);
            batchPlanRepository.save(batchPlan);
            return;
        }

        if (endDate == null) {
            endDate = new Date();
        }

        startDate = DateUtil.transDateFormat(startDate);
        Date date = startDate;
        endDate = DateUtil.transDateFormat(endDate);

        int noDayOffs = 0; // 工作日的天数
        while (date.before(endDate) || date.equals(endDate)) {
            FactoryCalendarItem fci = factoryCalendarItemRepository.findFactoryCalendarItemByDateAndFactoryCalendarAndDelete(date, factoryCalendar, 0);
            if (fci != null) {
                if (fci.getDayOff()) {
                    date = DateUtil.computeDate(date, 24);
                    continue;
                }
            }

            noDayOffs++;
            date = DateUtil.computeDate(date, 24);
        }
        // 更新产能日历
//        for (Date date = )
        System.out.println("productManufactInfor.getStandManufactWorkhour():" + productManufactInfor.getStandManufactWorkhour());
        System.out.println("noDayOffs" + noDayOffs);
        int workLoad = Math.round((productManufactInfor.getManufactWorkhour() == null ? 0 : productManufactInfor.getManufactWorkhour()) / noDayOffs);
        date = startDate;
        List<PlantCapacityCalendar> plantCapacityCalendars = new ArrayList<>();
        while (date.before(endDate) || date.equals(endDate)) {

            FactoryCalendarItem fci = factoryCalendarItemRepository.findFactoryCalendarItemByDateAndFactoryCalendarAndDelete(date, factoryCalendar, 0);
            if (fci != null) {
                if (fci.getDayOff()) {
                    date = DateUtil.computeDate(date, 24);
                    continue;
                }
            }
            PlantCapacityCalendar plantCapacityCalendar = null;
            // 根据柜体id和工序id和时间获取到某天的产能
            if (bp != null) {
                plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchProductIdAndDateAndProcessIdAndUserIdAndDelete(product.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), userWorkHourInfo.getUserId(), 0);
            } else {
                plantCapacityCalendar = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchPlanIdAndDateAndProcessIdAndUserIdAndDelete(batchPlan.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), userWorkHourInfo.getUserId(), 0);

//                List<PlantCapacityCalendar> plants = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchPlanIdAndDateAndProcessIdAndDelete(batchPlan.getId(), DateUtil.computeDate(DateUtil.transDateFormat(date),9), productManufactInfor.getProcessId(), 0);
//                if (!plants.isEmpty()) {
//                    plantCapacityCalendar = plants.get(0);
//
//                }
            }
            if (plantCapacityCalendar == null) {
                plantCapacityCalendar = new PlantCapacityCalendar();
                plantCapacityCalendar.setWorkHour((float) 0);
                plantCapacityCalendar.setRealWorkHour((float) 0);
            }
            plantCapacityCalendar.setDate(DateUtil.computeDate(date, 9));
            if (bp != null) {
                plantCapacityCalendar.setBatchProductId(product.getId());
                plantCapacityCalendar.setBatchProductCode(product.getProductCode());
            }
            plantCapacityCalendar.setBatchPlanId(batchPlan.getId());
            plantCapacityCalendar.setProjectName(batchPlan.getProjectName());
            plantCapacityCalendar.setProjectCode(info == null ? null : info.getProjectCode());
            plantCapacityCalendar.setBatchPlanCode(batchPlan.getBatchPlanCode());
            plantCapacityCalendar.setProcessName(productManufactInfor.getProcessName());
            plantCapacityCalendar.setProcessCode(productManufactInfor.getProcessCode());
            plantCapacityCalendar.setProcessSequence(productManufactInfor.getSequence());
            plantCapacityCalendar.setProcessId(productManufactInfor.getProcessId());
            plantCapacityCalendar.setUserId(userWorkHourInfo.getUserId());
            plantCapacityCalendar.setUserName(userWorkHourInfo.getUserName());
            plantCapacityCalendar.setRealWorkHour(userWorkHourInfo.getManufactWorkhour() + workLoad);
//            plantCapacityCalendar.setWorkHour((float) 0);
            plantCapacityCalendars.add(plantCapacityCalendar);
//                plantCapacityCalendar.set
//            plantCapacityCalendarRepository.save(plantCapacityCalendar);
            date = DateUtil.computeDate(date, 24);

        }
        plantCapacityCalendarRepository.saveAll(plantCapacityCalendars);
        batchPlan.setIsSchduling(0);
        batchPlanRepository.save(batchPlan);
    }


    /**
     * 生成某天某个工序的计划产能负荷
     *
     * @param date
     * @return
     */
    @Override
    public Float computeCapacitySumByDay(Date date, Process process) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            date = df.parse(df.format(date));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Float workOff = 0f;
        if (process == null) {
            workOff = plantCapacityCalendarRepository.sumWorkHourByDate(date, 0);
        } else {
            workOff = plantCapacityCalendarRepository.sumWorkHourByDateAndProcess(date, process.getId(), 0);
        }
        if (workOff == null) {
            workOff = 0f;
        }

        return workOff;
    }

    /**
     * 生成某天某个工序的实际产能负荷
     *
     * @param date
     * @param process
     * @return
     */
    @Override
    public Float computeRealCapacitySumByDay(Date date, Process process) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            date = df.parse(df.format(date));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Float workOff = 0f;
        if (process == null) {
            workOff = plantCapacityCalendarRepository.sumRealWorkHourByDate(date, 0);
        } else {
            workOff = plantCapacityCalendarRepository.sumRealWorkHourByDateAndProcess(date, process.getId(), 0);
        }
        if (workOff == null) {
            workOff = 0f;
        }

        return workOff;
    }


    /**
     * 更新产能日历
     *
     * @param batchProduct
     */
    @Override
    public void updatePlantCapCalender(BatchProduct batchProduct, BatchPlan batchPlan) {

        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByCalendarCodeAndDelete("standard1", 0);

        List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductIdAndDelete(batchProduct.getId(), 0);
        for (ProductManufactInfor p : productManufactInfors) {
//            System.out.println("batchProduct+ProductManufactInfor"+batchProduct.getId()+"..."+p.getProcessId());
            plantCapacityCalendarRepository.updatePlanCapByBatchProductIdAndProcessId(batchProduct.getId(), p.getProcessId());
//            System.out.println("delete:"+delete);
            // 重新生成计划产能日历
//            generateCapacityCalendar(p, batchProduct, factoryCalendar, batchPlan);
//            // 重新生成实际产能日历
            generateCapacityCalendar(p, batchProduct, factoryCalendar, batchPlan);

//            generateRealCapacityCalendar(p);
        }
    }

    /**
     * 按批次更新计划产能日历
     *
     * @param batchPlan
     */
    @Override
    public void updatePlantCapCalenderByBatchPlan(BatchPlan batchPlan) {

        // 直接按照batchPlan更新
        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByCalendarCodeAndDelete("standard1", 0);
        // 将该批次的所有产能清空。
        plantCapacityCalendarRepository.clearPlanCapByBatchPlanId(batchPlan.getId());
        // 得首先获取到该批次下的所有工序 -- 每道工序 都有自己的时间， 必须单独计算，然后累加。
        List<String> productIds = batchProductRepository.getBatchProductIdsByBatchPlanIdAndDelete(batchPlan.getId(), 0);
        for (ProductManufactInfor productManufactInfor : productManufactInforRepository.findProductManufactInforsByBatchProductIdInAndDelete(productIds, 0)) {
            BatchProduct batchProduct = batchProductRepository.findBatchProductById(productManufactInfor.getBatchProductId());
            generateCapacityCalendar(productManufactInfor, batchProduct, factoryCalendar, batchPlan);
        }
        batchPlan.setWorkHour(plantCapacityCalendarRepository.sumCapSumByBatchPlan(batchPlan.getId(), 0));
        batchPlanRepository.save(batchPlan);
    }

    /**
     * 更新实际产能日历
     *
     * @param batchProduct
     */
    @Override
    public void updateRealPlantCapCalender(BatchProduct batchProduct, BatchPlan batchPlan) {

        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByCalendarCodeAndDelete("standard1", 0);

        List<ProductManufactInfor> productManufactInfors = productManufactInforRepository.findProductManufactInforsByBatchProductIdAndDelete(batchProduct.getId(), 0);
        for (ProductManufactInfor p : productManufactInfors) {
//            System.out.println("batchProduct+ProductManufactInfor"+batchProduct.getId()+"..."+p.getProcessId());
            plantCapacityCalendarRepository.updateRealCapByBatchProductIdAndProcessId(batchProduct.getId(), p.getProcessId());
//            System.out.println("delete:"+delete);
            generateCapacityCalendar(p, batchProduct, factoryCalendar, batchPlan);
//            generateRealCapacityCalendar(p,ba);
        }
    }

    /**
     * 按批次更新实际产能日历
     *
     * @param batchPlan
     */
    @Override
    public void updateRealPlantCapCalenderByBatchPlan( BatchPlan batchPlan) {
        // 直接按照batchPlan更新
        FactoryCalendar factoryCalendar = factoryCalendarRepository.findFactoryCalendarByCalendarCodeAndDelete("standard1", 0);
        // 将该批次的所有实际工时清空。
        plantCapacityCalendarRepository.clearRealPlanCapByBatchPlanId(batchPlan.getId());
        // 得首先获取到该批次下的所有工序 -- 每道工序 都有自己的时间， 必须单独计算，然后累加。
        List<String> productIds = batchProductRepository.getBatchProductIdsByBatchPlanIdAndDelete(batchPlan.getId(), 0);
        for (ProductManufactInfor productManufactInfor : productManufactInforRepository.findProductManufactInforsByBatchProductIdInAndDelete(productIds, 0)) {
            for (UserWorkHourInfo userWorkHourInfo : userWorkHourInfoRepository.findUserWorkHourInfoByProcessIdAndDelete(productManufactInfor.getId(), 0)) {
                generateRealCapacityCalendar(productManufactInfor,userWorkHourInfo, null, factoryCalendar, batchPlan);
            }
        }
        Float v = plantCapacityCalendarRepository.sumRealCapSumByBatchPlan(batchPlan.getId(), 0);
        batchPlan.setRealWorkHour(v == null ? null : NumberUtil.roundTwo(v / 3600));
        batchPlanRepository.save(batchPlan);
    }



    /**
     * 生成某天 再指定范围的产能符合
     *
     * @param date    开始日期或结束日期
     * @param range   指定日期的天数范围， 正数表示date向后range天数， 负数表示date向前range天数
     * @param process 指定工序， 若为null， 则表示全部工序之和
     * @return
     */
    @Override
    public List<DateRangeCapacity> computeCapacitySumByDayAndRange(Date date, int range, Process process) {
        List<DateRangeCapacity> dateRangeCapacities = new ArrayList<>();
        Date startDate;
        Date endDate;
        // 如果范围是0， 只返回当天的数据
        if (range == 0) {
            DateRangeCapacity dateRangeCapacity = new DateRangeCapacity();
            dateRangeCapacity.setDate(date);
            dateRangeCapacity.setCapacityLoad(computeCapacitySumByDay(date, process));
            dateRangeCapacities.add(dateRangeCapacity);
            return dateRangeCapacities;
        }
        // 大于0 找出开始和结束日期
        if (range > 0) {
            startDate = DateUtil.transDateFormat(date);  // 指定日期
            endDate = DateUtil.computeDate(date, (range - 1) * 24); //

//            System.out.println("startDate:"+startDate+"\tendDate:"+endDate);
        } else {

            startDate = DateUtil.transDateFormat(DateUtil.computeDate(date, (range + 1) * 24));
            endDate = DateUtil.transDateFormat(date);
        }
        Date date1 = DateUtil.computeDate(startDate, 9);
        Float workhour;
        while (DateUtil.transDateFormat(date1).before(DateUtil.transDateFormat(endDate)) || DateUtil.transDateFormat(date1).equals(DateUtil.transDateFormat(endDate))) {
            if (process == null) {
                workhour = plantCapacityCalendarRepository.sumWorkHourByDate(date1, 0);
            } else {
                workhour = plantCapacityCalendarRepository.sumWorkHourByDateAndProcess(date1, process.getId(), 0);
            }

            DateRangeCapacity dateRangeCapacity = new DateRangeCapacity();
            dateRangeCapacity.setDate(date1);
            dateRangeCapacity.setCapacityLoad(workhour == null ? 0 : workhour);
            dateRangeCapacities.add(dateRangeCapacity);
            date1 = DateUtil.computeDate(date1,24);
        }
        return dateRangeCapacities;
    }

    /**
     * 生成某天 再指定范围的计划产能负荷
     *
     * @param date    开始日期或结束日期
     * @param range   指定日期的天数范围， 正数表示date向后range天数， 负数表示date向前range天数
     * @param process 指定工序， 若为null， 则表示全部工序之和
     * @return
     */
    @Override
    public List<DateRangeCapacity> computeRealCapacitySumByDayAndRange(Date date, int range, Process process) {
        List<DateRangeCapacity> dateRangeCapacities = new ArrayList<>();
        Date startDate;
        Date endDate;
        // 如果范围是0， 只返回当天的数据
        if (range == 0) {
            DateRangeCapacity dateRangeCapacity = new DateRangeCapacity();
            dateRangeCapacity.setDate(date);
            dateRangeCapacity.setCapacityLoad(computeCapacitySumByDay(date, process));
            dateRangeCapacities.add(dateRangeCapacity);
            return dateRangeCapacities;
        }
        // 大于0 找出开始和结束日期
        if (range > 0) {
            startDate = DateUtil.transDateFormat(date);  // 指定日期
            endDate = DateUtil.computeDate(date, (range - 1) * 24); //

//            System.out.println("startDate:"+startDate+"\tendDate:"+endDate);
        } else {

            startDate = DateUtil.transDateFormat(DateUtil.computeDate(date, (range + 1) * 24));
            endDate = DateUtil.transDateFormat(date);
        }
        Date date1 = DateUtil.computeDate(startDate, 9);
        Float workhour;
        while (DateUtil.transDateFormat(date1).before(DateUtil.transDateFormat(endDate)) || DateUtil.transDateFormat(date1).equals(DateUtil.transDateFormat(endDate))) {
            if (process == null) {
                workhour = plantCapacityCalendarRepository.sumRealWorkHourByDate(date1, 0);
            } else {
                workhour = plantCapacityCalendarRepository.sumRealWorkHourByDateAndProcess(date1, process.getId(), 0);
            }

            DateRangeCapacity dateRangeCapacity = new DateRangeCapacity();
            dateRangeCapacity.setDate(date1);
            dateRangeCapacity.setCapacityLoad(workhour == null ? 0 : workhour);
            dateRangeCapacities.add(dateRangeCapacity);
            date1 = DateUtil.computeDate(date1,24);
        }
        return dateRangeCapacities;
    }

    @Override
    public void updateRealPlantCapCalenderByBatchPlan(ProductManufactInfor productManufactInfor){

        BatchProduct product = batchProductRepository.findBatchProductByIdAndDelete(productManufactInfor.getBatchProductId(), 0);
        if (product == null) {
            throw new BeadminException("未找到该工序的柜体");
        }
        BatchPlan plan = batchPlanService.getBatchPlanById(product.getBatchPlanId());
        if (plan == null) {
            throw new BeadminException("未找到plan");
        }
        updateRealPlantCapCalenderByBatchPlan(plan);
    }
    /**
     * 获取产能日历数据 - 按照批次统计
     *
     * @param pageEntity
     * @return
     */
    @Override
    public Page<CapacityByBatchAndDayEx> getPlantCapacityCalendarByPageAndBatch(PageEntity pageEntity) {
//
//        getCapacityByBatch();
//
//        // 更新批次的产能
//
//        List<String> batchPlanIds = plantCapacityCalendarRepository.findBatchPlanIdsByDelete(0);
//        for (int i = 0; i < batchPlanIds.size(); i++) {
//            // 工序 -- 日期  -- 批次
////            plantCapacityCalendarRepository.sumRealWorkHourByBatchAndDateAndProcess(batchPlanIds.get(i),)
//        }
//
//
//        Page<PlantCapacityCalendarEx> plantCapacityCalendarByPage = null;
//        for (FilderExpressEntity filter : pageEntity.getFilters()) {
//            if (filter.getField().equals("batchPlanCode")) { // 用批次计划编码查询
//
//
//            }
//        }
//
//        plantCapacityCalendarByPage = getPlantCapacityCalendarByPage(pageEntity);
//        Page<CapacityByBatchAndDayEx> map = plantCapacityCalendarByPage.map(new Function<PlantCapacityCalendarEx, CapacityByBatchAndDayEx>() {
//            @Override
//            public CapacityByBatchAndDayEx apply(PlantCapacityCalendarEx plantCapacityCalendarEx) {
//                for (String batchPlanId:
//                batchPlanIds) {
//                    if (plantCapacityCalendarEx.getBatchPlanId().equals(batchPlanId)) {
//
//                        plantCapacityCalendarEx.getProcessId();
//                        plantCapacityCalendarEx.getDate();
//                    }
//                }
//                return null;
//            }
//        });
//      re
//        return map;
        return null;
    }


    @Override
    public List<CapacityByBatchAndDayEx> getCapacityByBatch() {

//        // 获取所有批次
//        List<String> batchPlanIds = plantCapacityCalendarRepository.findBatchPlanIdsByDelete(0);
//        // 获取所有日期
//        List<Date> dates = plantCapacityCalendarRepository.findDatesByDelete(0);
//        // 获取所有工序
//        List<String> processIds = plantCapacityCalendarRepository.findProcessIdsByDelete(0);
//
//
//
//        List<CapacityByBatchAndDayEx> capacitys = new ArrayList<>();
//        for (int i = 0; i < batchPlanIds.size(); i++) {
//            String batchPlanId = batchPlanIds.get(i);
//            BatchPlan plan = batchPlanRepository.findBatchPlanByIdAndDelete(batchPlanId, 0);
//            for (int j = 0; j < processIds.size(); j++) {
//                String processId = processIds.get(j);
//                Process process = processRepository.findProcessByIdAndDelete(processId, 0);
//                for (int k = 0; k < dates.size(); k++) {
//                    Date date = DateUtil.transDateFormat(dates.get(k));
//                    CapacityByBatchAndDayEx capacity = new CapacityByBatchAndDayEx();
//                    capacity.setBatchPlanId(batchPlanId);
//                    capacity.setBatchPlanCode(plan.getBatchPlanCode());
//                    capacity.setProcessId(processId);
//                    capacity.setProcessName(process.getProcessName());
//                    capacity.setProcessCode(process.getProcessCode());
//                    capacity.setDate(date);
//                    capacity.setWorkHour(plantCapacityCalendarRepository.sumWorkHourByBatchAndDateAndProcess(batchPlanIds.get(i),date,processId,0));
//                    capacity.setRealWorkHour(plantCapacityCalendarRepository.sumRealWorkHourByBatchAndDateAndProcess(batchPlanIds.get(i),date,processId,0));
//                    capacitys.add(capacity);
//                }
//            }
//        }
//        return capacitys;
        return null;
    }

    @Override
    public void delPlantCapacityCalendarsByBatchPlan(BatchPlan batchPlan) {
        plantCapacityCalendarRepository.deletePlantCapacityCalendarsByBatchPlanId(batchPlan.getId());
    }

    @Override
    public List<PlantCapacityCalendar> getWorkingHoursComparisonsByProductCode(String productCode) {
        List<PlantCapacityCalendar> plantCapacityCalendarList = plantCapacityCalendarRepository.findPlantCapacityCalendarByBatchProductCodeAndDelete(productCode , 0);
        return plantCapacityCalendarList;
    }
}